---
sidebar_position: 5
title: Why Hyper Fetch is Unique
sidebar_label: Comparison
---

import { Info } from "lucide-react";
import Tippy from "@tippyjs/react";
import "tippy.js/dist/tippy.css";

# Comparison

The biggest difference between **`Hyper Fetch`** and other libraries is the opinionated architecture and assumptions on
which it is built. Hyper Fetch's core features are written in TS **without dependencies**; because of this, it can work
in many environments without a specific connection to a given framework.

:::info

Producing an accurate and unbiased comparison is quite a challenge. Libraries develop quickly, so if you notice that our
data needs to be corrected, please let us know by opening an issue.

:::

---

## Why Hyper Fetch Is Unique

- Easy upload/download progress and ETA tracking
- Supports request queueing and many [dispatching strategies](/core/dispatcher.mdx#dispatching-modes)!
- [Command](/core/request.mdx) / [Builder](/core/client.mdx) pattern gives you amazing control over requests at any time
- Code-sharing architecture lets [testers to hook into development setup and types](/guides/testing/index.mdx)
- Features flat side-effects [helper hooks annotation](/react/overview.mdx#helper-hooks) and promotes readable code
- Provides structure [recipes](/getting-started/development.mdx#structure) for large scale applications that
  significantly limit maintenance costs.
- Core features include [offline](/guides/core/02-advanced/offline.mdx) and
  [persistence](/guides/core/02-advanced/persistence.mdx) support, giving you full control over your data

---

## Features

<div>✅ - Documented support</div>
<div>🚧 - Work in progress</div>
<div>🔵 - Require additional Plugin/Coding</div>
<div>🔴 - Not supported / Not documented</div>

<br />
<br />

<div className="comparison-table">
  <table>
    <thead>
      <tr>
        <th></th>
        <th>Hyper Fetch</th>
        <th>
          <a href="https://tanstack.com/query/v4/?from=reactQueryV3&original=https://react-query-v3.tanstack.com/">
            Query
          </a>
        </th>
        <th>
          <a href="https://swr.vercel.app/">SWR</a>
        </th>
        <th>
          <a href="https://www.apollographql.com/documentation/04-react/">Apollo</a>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Supported environments</td>
        <td>Any</td>
        <td>Any</td>
        <td>React</td>
        <td>Any</td>
      </tr>
      <tr>
        <td>Protocols</td>
        <td>Any</td>
        <td>Any</td>
        <td>Any</td>
        <td>GraphQL</td>
      </tr>
      <tr>
        <td>Caching Approach</td>
        <td>Request Schema</td>
        <td>Hierarchical Key > Value</td>
        <td>Unique Key > Value</td>
        <td>Normalized Schema</td>
      </tr>
      <tr>
        <td>Cache Key Strategy</td>
        <td>Request Key</td>
        <td>JSON</td>
        <td>JSON</td>
        <td>GraphQL Query</td>
      </tr>
      <tr>
        <td>Data Change Detection</td>
        <td>Deep Comparison</td>
        <td>Deep Comparison</td>
        <td>Deep Comparison</td>
        <td>Deep Comparison</td>
      </tr>
      <tr>
        <td>Data Memoization</td>
        <td>Identity</td>
        <td>Full Structural Sharing</td>
        <td>Identity</td>
        <td>Normalized Identity</td>
      </tr>
      <tr>
        <td>Queue Key Strategy</td>
        <td>Request Key</td>
        <td>N/A</td>
        <td>N/A</td>
        <td>N/A</td>
      </tr>
      <tr>
        <td>Devtools</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to prepare global setup for server connection">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Server Connection Setup
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to prepare requests to be reused in the application">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Shared Request
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="It allows to limit re-rendering only to the dependent key changes">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Dependency tracking
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>Cache Persistence</td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Possibility to keep data prepared for request in persistent storage and resend it on new session">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Requests Persistence
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Tracking of the download progress to being able to access size left and time ETA">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Download ETA
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Tracking of the upload progress to being able to access size left and time ETA">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Uploading ETA
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Fetch new data at interval">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Pooling
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to hold on one request until another is finished">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Dependent Queries
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>Paginated Queries</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Built-in query parsing from object or string">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Query Params Parsing
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Allows to group requests in queues and control sending process">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Queueing
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="When request fails try again to trigger it">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Retries
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Library includes prepared adapter for requesting">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Default Adapter
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="When we want to dynamically 'load more' content on the list">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Infinite Queries
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Server Side Rendering">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              SSR
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Initialize with prepared placeholder data">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Initial Data
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Allows to hydrate cache storage with data from other sources">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Cache Hydration
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Stale data gets removed from memory">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Garbage Collecting
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Intercept and modify every request before being triggered">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Pre Request Intercepting
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Intercept and modify every response before being saved and emitted">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Post Request Intercepting
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Prefetch your data before your components being mounted">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Prefetching
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Cancel ongoing request">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Cancellation
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Cancel group of ongoing requests by their queue key">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Queue Cancellation
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Has built-in solutions for authentication like intercepting and possibilities to turn on/off">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Authentication
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Load cache data and refresh it in background">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Stale While Revalidate
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>Refresh Data</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="When app goes offline, it waits until connection is back and retries paused requests">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Offline Request Pause
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Trigger re-fetch when your app goes online">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Network Status Re-fetching
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Trigger re-fetch when you switch tabs or windows">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Window Focus Re-fetching
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Storing cached data in flat schema based architecture to prevent duplication">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Normalized Caching
            </div>
          </Tippy>
        </td>
        <td>🔴</td>
        <td>🔵</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Refresh cache data once you post mutation request">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Automatic Re-fetch After Mutation
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Make operations on queued queries by their keys - you can cancel, stop or delete them from queue.">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Query Matching
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Make operations on queries by their keys. Re-fetch groups of requests with partial names/regex or full keys.">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Cache Matching
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Receive every lifecycle response for any request. Request start, progress, response start, success, error, finished.">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Query Lifecycle Events
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Having standardized format for data exchange and for easy reading/dumping">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Data Flow Standard
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Possibility to control particular request in a queue.">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Request Start/Stop
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Possibility to control all queued requests.">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Request Queue Start/Stop/Pause
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Before we send a request we can map the data it's transferring to different format before it gets to server">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Request Data Mapping
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>N/A</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Invalidate cache data to re-fetch it.">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Cache Invalidation
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="File upload with built-in adapter">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              File Uploading
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="We can hook global listeners on a particular request to listen and trigger side effects while it's being send">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Global Response Side-Effects
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Going back to previous cache will restore scroll as data will be imminently shown to the user.">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Scroll Recovery
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Possibility to trigger requests requests">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Simple Request Execution
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Possibility to show requests being uploaded throughout the whole system. Works like uploading managers, but much more advanced.">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Requests Manager
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to synchronize tabs data">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Tabs Storages Synchronization
            </div>
          </Tippy>
        </td>
        <td>🔴</td>
        <td>🚧</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to synchronize not sent queries queues between tabs which is required to present full persistence in browser">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Tabs Dispatching Synchronization
            </div>
          </Tippy>
        </td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to listen and emit events">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Websocket
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to listen to server sent events">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Server Sent Events
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
    </tbody>
  </table>
</div>

---

## Typescript features

<div className="comparison-table">
  <table>
    <thead>
      <tr>
        <th></th>
        <th>Hyper Fetch</th>
        <th>
          <a href="https://tanstack.com/query/v4/?from=reactQueryV3&original=https://react-query-v3.tanstack.com/">
            Query
          </a>
        </th>
        <th>
          <a href="https://swr.vercel.app/">SWR</a>
        </th>
        <th>
          <a href="https://www.apollographql.com/documentation/04-react/">Apollo</a>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          <Tippy content="What data type you expect to receive from server">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Response types
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Pass the type to specify the data schema to be send">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Request data types
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Specify possible error responses for all requests in the system">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Global error types
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to specify particular endpoint errors apart from global error type">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Local error types
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to pass type checking for endpoint query params">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Query params types
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy content="Being able to automatically track the record of endpoint string">
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Params types
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          <Tippy
            showOnCreate
            content="Types to check if you already set the data/params/query params on given request to prevent data corruption"
          >
            <div className="flex items-center gap-2 w-fit">
              <Info className="w-4 h-4" />
              Request state tracking types
            </div>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
    </tbody>
  </table>
</div>
